<?php

namespace App\Helpers;

use Illuminate\Http\Resources\Json\ResourceCollection;
use Symfony\Component\HttpFoundation\Response as FoundationResponse;
use Illuminate\Support\Facades\Response;

trait ApiResponse
{
    /**
     * @var int
     */
    protected $statusCode = FoundationResponse::HTTP_OK;

    /**
     * @return mixed
     */
    public function getStatusCode()
    {
        return $this->statusCode;
    }

    /**
     * @param $statusCode
     * @return $this
     */
    public function setStatusCode($statusCode)
    {
        $this->statusCode = $statusCode;
        return $this;
    }

    /**
     * @param $data
     * @param array $header
     * @return mixed
     */
    public function respond($data, array $header = [])
    {
        $collectionObj = $data['data'] ?? '';

        if ($collectionObj instanceof ResourceCollection) {
            $collectionObj->additional([
                'code' => $data['code'],
                'status' => $data['status'],
            ]);
            return $collectionObj->toResponse(request());
        }

        return Response::json($data, $this->getStatusCode(), $header);
    }

    /**
     * @param array $data
     * @param string $status
     * @param $code
     * @return mixed
     */
    public function statusOut(array $data, string $status = 'success', $code = null)
    {
        if ($code) {
            $this->setStatusCode($code);
        }

        $status = [
            'code' => $this->statusCode,
            'status' => $status,
        ];

        $data = array_merge($status, $data);

        return $this->respond($data);
    }

    /**
     * @param $message
     * @param string $status
     * @return mixed
     */
    public function message($message, string $status = 'success')
    {
        return $this->statusOut([
            'data' => $message
        ], $status);
    }

    /**
     * @param $message
     * @param int $code
     * @param string $status
     * @return mixed
     */
    public function failed($message, int $code = FoundationResponse::HTTP_BAD_REQUEST, string $status = 'error')
    {
        return $this->setStatusCode($code)->message($message, $status);
    }

    /**
     * @param string $message
     * @return mixed
     */
    public function created(string $message = 'created')
    {
        return $this->setStatusCode(FoundationResponse::HTTP_CREATED)->message($message);
    }

    /**
     * @param $data
     * @return mixed
     */
    public function success($data)
    {
        return $this->statusOut(compact('data'));
    }
}
